package com.fjnu.aspect;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 *
 * 1. 用日志记录Dao层所有方法的执行开始时间 Before
 * 2. 用日志记录Dao层所有方法的执行花费时间 Around
 * 3.  todo: 用日志记录Dao层所有方法的执行结束时间 After
 *     todo: 用日志记录Dao层所有的delete方法的执行时间
 *      step 1: @Pointcut
 *      Step 2: @Advice
 *      Step 3: 编写测试
 *
 *
 *
 *
 *
 */
@Component
@Aspect
public class LogAspect {

    /**
     * Part one:  joinpoints  by pointcut
     */
    @Pointcut("execution(public * com.fjnu.dao.*.insert*(..))")
    public void daoLayer() {}

    // Step 1: 定义delete方法的Pointcut
    @Pointcut("execution(public * com.fjnu.dao.*.delete*(..))")
    public void daoDeleteLayer() {}

    /**
     * Part two: advices: enhanced functional
     *
     */

    @Before("daoLayer()")
    public void logStartTimeAdvice(JoinPoint jp) throws Exception {

        /**
         * Enhanced functional
         */
        String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                .format(new Date()) ;
        System.out.println("[INFO] [BeforeAdvice] the method: "
                   + jp.getSignature().getName()
                     +" was executed at " + currentTime) ;


    }


    @Around("daoLayer()")
    public Object performanceLogAdvice(ProceedingJoinPoint pjp) throws Throwable {

        long startTime = System.currentTimeMillis() ;
        // before it execution, enhanced functional could add here.

        Object ret = pjp.proceed() ; // - ->  target method execution .
        // after the point,  here could be added enhanced functional
        System.out.println("[INFO] [Around Advice] the method "
                + pjp.getSignature().getName()
                + " was executed for " + (System.currentTimeMillis() - startTime)
                + " ms" );
        return ret ;
    }
    // Step 2: 记录所有Dao层方法的执行结束时间
    @After("execution(public * com.fjnu.dao.*.*(..))")
    public void logEndTimeAdvice(JoinPoint jp) {
        String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                .format(new Date());
        System.out.println("[INFO] [AfterAdvice] the method: "
                + jp.getSignature().getName()
                + " execution ended at " + currentTime);
    }

    // Step 2: 记录delete方法的执行时间
    @Around("daoDeleteLayer()")
    public Object deletePerformanceLogAdvice(ProceedingJoinPoint pjp) throws Throwable {
        long startTime = System.currentTimeMillis();

        Object ret = pjp.proceed();

        long executionTime = System.currentTimeMillis() - startTime;
        System.out.println("[INFO] [Delete Around Advice] the delete method "
                + pjp.getSignature().getName()
                + " was executed for " + executionTime + " ms");

        return ret;
    }

}
